home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / mj90.lha / ASCII / CpuIdIII-35.ascii < prev    next >
Encoding:
Text File  |  1993-12-07  |  8.2 KB  |  313 lines

  1. (c)  Copyright 1990 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice,
  3. and  is provided "as is" without warranty of any kind, either express
  4. or implied.   The entire risk as to the use of this information is
  5. assumed by the user.
  6.  
  7. Identifying the Amiga's CPU
  8.  
  9. by Dave Haynie
  10.  
  11. Amiga's come in a variety of configurations including models that
  12. use the Motorola 68000, the 68020 and now the 68030.  While it's
  13. not that  difficult to figure out which CPU you're using by
  14. trying certain instructions  and trapping the exception if they
  15. break, this isn't necessary.  In fact, the  Amiga OS sets an
  16. ExecBase flag on system startup that can identify which 
  17. processor (and coprocessor) is installed.  The CPU type flags are
  18. stored  in ExecBase->AttnFlags.  
  19.  
  20. Under V1.3 and earlier versions of the OS, the system can't tell
  21. the  difference between a 68020 and a 68030, or a 68881 and a
  22. 68882.  That's no big surprise, since both the 68030 and 68882
  23. were introduced well after the last version of the OS was
  24. released.  Under the new V2.0 version of the  operating system,
  25. support for identifying these processors has been added.  If you
  26. are running under V2.0 of the operating system, you can just look
  27. at ExecBase->AttnFlags to find out what processor is installed. 
  28. The AttnFlags field will be set as follows:
  29.  
  30. /****** V2.0 Bit defines for AttnFlags ************************/
  31.  
  32. /*  Processors and Co-processors: */
  33. #define AFB_68010    0    /*  also set for 68020  */
  34. #define AFB_68020    1    /*  also set for 68030  */
  35. #define AFB_68030    2    /* New flag under V2.0  */
  36. #define AFB_68040    3    /* New flag under V2.0  */
  37. #define AFB_68881    4    /*  also set for 68882  */
  38. #define AFB_68882    5    /* New flag under V2.0  */
  39.  
  40. #define AFF_68010    (1L<<0)
  41. #define AFF_68020    (1L<<1)
  42. #define AFF_68030    (1L<<2)    /* New flag under V2.0  */
  43. #define AFF_68040    (1L<<3)    /* New flag under V2.0  */
  44. #define AFF_68881    (1L<<4)
  45. #define AFF_68882    (1L<<5)    /* New flag under V2.0  */
  46.  
  47. However, if you are running under V1.3 or earlier versions of the
  48. operating  system, this method will not work with the 68030 and
  49. 68882 processors.  To  overcome this problem you can use the code
  50. shown below to identify which  CPU the system is using under
  51. V1.3.  There are three functions to link with  your code to
  52. identify the processor and coprocessor: GetCPUType(),
  53. GetFPUType(), and GetMMUType().
  54.  
  55. o ULONG GetCPUType(void)
  56.  
  57.     Returns a number, representing the type of CPU in the 
  58.     system: 68000L, 68010L, 68020L, or 68030L.
  59.  
  60. o ULONG GetFPUType(void)
  61.  
  62.     Returns a number, representing the type of FPU in the 
  63.     system: 0L (no FPU), 68881L, or 68882L.
  64.  
  65. o ULONG GetMMUType(void)
  66.  
  67.     Returns a number, representing the type of MMU in the 
  68.     system: 0L (no MMU), 68851L, 68030L, or 0xFFFFFFFFL
  69.     (this means an FPU responding to a MMU address).
  70.  
  71.  
  72. In order to find out which processor is present, GetCPUType()
  73. first checks  ExecBase->AttnFlags.  Under V1.3 if this is set to
  74. AFF_68020, then the  processor may be either a 68020 or a 68030. 
  75. GetCPUType() then checks to  see if the processor is really a
  76. 68030 by trying to invert the instruction  burst enable bit,
  77. which doesn't exist on the 68020.  If that bit can be  changed,
  78. then it is a 68030 system.   
  79.  
  80. Similar methods are used in GetMMUType() and GetFPUType().  These
  81. functions  first look at ExecBase->AttnFlags and then do extra
  82. tests based on unique features of a given coprocessor to find out
  83. what is present in the system.  The functions are listed below.
  84.  
  85.  
  86. ;
  87. ;    From SetCPU V1.5
  88. ;    by Dave Haynie 
  89. ;
  90. ;    68030 Assembly Function Module
  91. ;
  92. ;    This module contains functions that access features of the 68020,
  93. ;    68030, and 68851 chips, and ID all of these, plus the 68881/68882
  94. ;    FPU chips, reset stuff, and exception handler.
  95. ;
  96.  
  97.  
  98.  
  99. ;
  100. ;    Macros & constants used herein...
  101. ;
  102.  
  103.  
  104.     section code
  105.  
  106. CALLSYS macro   *
  107.     jsr     LVO\1(A6)
  108.     endm
  109.  
  110. CIB_ENABLE    EQU    0
  111. CIB_FREEZE    EQU    1
  112. CIB_ENTRY    EQU    2
  113. CIB_CLEAR    EQU    3
  114. CIB_BURST    EQU    4
  115.  
  116. CDB_ENABLE    EQU    8
  117. CDB_FREEZE    EQU    9
  118. CDB_ENTRY    EQU    10
  119. CDB_CLEAR    EQU    11
  120. CDB_BURST    EQU    12
  121. CDB_WALLOC    EQU    13
  122.  
  123. AFB_68030    EQU    2
  124.  
  125. ATNFLGS        EQU    $129
  126.  
  127. LVOSupervisor    EQU    -30
  128. LVOSuperState    EQU    -150
  129. LVOFindTask    EQU    -294
  130. LVOAllocTrap    EQU    -342
  131. LVOFreeTrap    EQU    -348
  132.  
  133.  
  134. ;
  135. ;    Need just a little more stuff
  136. ;
  137.  
  138.  
  139.     NOLIST
  140.     include "exec/execbase.i"
  141.     include "exec/tasks.i"
  142.     LIST
  143.  
  144. *    machine mc68020
  145. *        mc68881
  146.  
  147.  
  148. ;**********************************************************************
  149. ;
  150. ;    This section contains functions that identify and operate on CPU 
  151. ;    things.
  152. ;
  153. ;**********************************************************************
  154.  
  155.     XDEF    _GetCPUType    ; ID the CPU
  156.     XDEF    _GetFPUType    ; ID the FPU
  157.     XDEF    _GetMMUType    ; ID the MMU
  158.  
  159.  
  160. ;
  161. ;    This function returns the type of the CPU in the system as a
  162. ;    longword: 68000, 68010, 68020, or 68030.  The testing must be done
  163. ;    in reverse order, in that any higher CPU also has the bits set for
  164. ;    a lower CPU.  Also, since 1.3 doesn't recognize the 68030, if I
  165. ;    find the 68020 bit set, I always check for the presence of a 
  166. ;    68030.
  167. ;
  168. ;    This routine should be the first test routine called under 1.2
  169. ;    and 1.3.
  170. ;
  171. ;    ULONG GetCPUType(void);
  172. ;
  173.  
  174.  
  175. _GetCPUType:
  176.     movem.l    a4/a5,-(sp)        ; Save this register
  177.     move.l    4,a6            ; Get ExecBase
  178.     btst.b    #AFB_68030,ATNFLGS(a6)    ; Does the OS think an '030 is here?
  179.     beq    0$
  180.     move.l    #68030,d0        ; Sure does...
  181.     movem.l    (sp)+,a4/a5
  182.     rts
  183. 0$
  184.     btst.b    #AFB_68020,ATNFLGS(a6)    ; Maybe a 68020?
  185.     bne    2$
  186.     btst.b    #AFB_68010,ATNFLGS(a6)    ; Maybe a 68010?
  187.     bne    1$
  188.     move.l    #68000,d0        ; Just a humble '000
  189.     movem.l    (sp)+,a4/a5
  190.     rts
  191. 1$
  192.     move.l    #68010,d0        ; Yup, we're an '010
  193.     movem.l    (sp)+,a4/a5
  194.     rts
  195. 2$
  196.     move.l    #68020,d0        ; Assume we're an '020
  197.     lea    3$,a5            ; Get the start of the supervisor code
  198.     CALLSYS    Supervisor
  199.     movem.l    (sp)+,a4/a5
  200.     rts
  201. 3$
  202.     movec    cacr,d1            ; Get the cache register
  203.     move.l    d1,a4            ; Save it for a minute
  204.     bset.l    #CIB_BURST,d1        ; Set the inst burst bit
  205.     bclr.l    #CIB_ENABLE,d1        ; Clear the inst cache bit
  206.     movec    d1,cacr            ; Try to set the CACR
  207.     movec    cacr,d1
  208.     btst.l    #CIB_BURST,d1        ; Do we have a set burst bit?
  209.     beq    4$
  210.     move.l    #68030,d0        ; It's a 68030
  211.     bset.b    #AFB_68030,ATNFLGS(a6)
  212. 4$
  213.     move.l    a4,d1            ; Restore the original CACR
  214.     movec    d1,cacr
  215.     rte
  216.  
  217.  
  218. ;
  219. ;    This function returns 0L if the system contains no MMU, 
  220. ;    68851L if the system does contain an 68851, or 68030L if the
  221. ;    system contains a 68030 (built-in MMU).
  222. ;
  223. ;    This code runs just fine on boards from Ronin and 
  224. ;    Commodore, as well as all 68030 boards it's been tested on.
  225. ;
  226. ;    ULONG GetMMUType(void)
  227. ;
  228.  
  229.  
  230. _GetMMUType:
  231.     move.l    4,a6            ; Get ExecBase
  232.     movem.l    a3/a4/a5,-(sp)        ; Save this stuff
  233.     move.l    #0,a1    
  234.     CALLSYS    FindTask        ; Call FindTask(0L)
  235.     move.l    d0,a3
  236.  
  237.     move.l    TC_TRAPCODE(a3),a4    ; Change the exception vector
  238.     move.l    #2$,TC_TRAPCODE(a3)
  239.     
  240.     move.l    #-1,d0            ; Try to detect undecode FPU
  241.     subq.l    #4,sp            ; Let's try an MMU instruction
  242.     dc.w    $f017            ; like PMOVE tc,(sp)
  243.     dc.w    $4200
  244.     cmpi    #0,d0            ; Any MMU here?
  245.     beq    1$
  246.     cmpi    #-1,d0            ; Hardware "features"?
  247.     beq    1$
  248.     btst.b    #AFB_68030,ATNFLGS(a6)    ; Does the OS think an '030 is here?
  249.     beq    1$
  250.     move.l    #68030,d0
  251.  
  252. 1$
  253.     addq.l    #4,sp            ; Return that local
  254.     move.l    a4,TC_TRAPCODE(a3)    ; Reset exception stuff
  255.     movem.l    (sp)+,a3/a4/a5        ; and return the registers
  256.     rts
  257.  
  258.     ; This is the exception code.  No matter what machine we're on,
  259.     ; we get an exception.  If the MMU's in place, we should get a
  260.     ; privilige violation; if not, an F-Line emulation exception.
  261. 2$
  262.     move.l    (sp)+,d0        ; Get Amiga supplied exception #
  263.     cmpi    #11,d0            ; Is it an F-Line?
  264.     beq    3$            ; If so, go to the fail routine
  265.     move.l    #68851,d0        ; We have MMU
  266.     addq.l    #4,2(sp)        ; Skip the MMU instruction
  267.     rte
  268. 3$
  269.     moveq.l    #0,d0            ; It dinna woik,
  270.     addq.l    #4,2(sp)        ; Skip the MMU instruction
  271.     rte
  272.  
  273. ;
  274. ;    This function returns the type of the FPU in the system as a
  275. ;    longword: 0 (no FPU), 68881, or 68882.
  276. ;
  277. ;    ULONG GetFPUType(void);
  278. ;
  279.  
  280.  
  281. _GetFPUType:
  282.     move.l    a5,-(sp)        ; Save this register
  283.     move.l    4,a6            ; Get ExecBase
  284.     btst.b    #AFB_68881,ATNFLGS(a6)    ; Does the OS think an FPU is here?
  285.     bne    1$    
  286.     moveq.l    #0,d0            ; No FPU here
  287.     move.l    (sp)+,a5        ; Give back the register
  288.     rts
  289. 1$
  290.     lea    2$,a5            ; Get the start of the supervisor code
  291.     CALLSYS    Supervisor
  292.     move.l    (sp)+,a5        ; Give back registers
  293.     rts
  294. 2$
  295.     move.l    #68881,d0        ; Assume we're a 68881
  296.     fsave    -(sp)            ; Test and check
  297.     moveq.l    #0,d1
  298.     move.b    1(sp),d1        ; Size of this frame
  299.     cmpi    #$18,d1
  300.     beq 3$
  301.     move.l    #68882,d0        ; It's a 68882
  302. 3$
  303.     frestore (sp)+            ; Restore the stack
  304.     rte
  305.  
  306.     end
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.